package model.scaling;

import java.util.List;
import java.util.NoSuchElementException;

import model.auxillary.DuplicateNameException;
import model.auxillary.ParameterListScaling;

//#Neu
/**
 * Interface for the {@code EBenchmarkScaling} class.
 * @author Sebastian Perlwitz
 *
 */
public interface IEBenchmarkScaling extends ICalculatableScaling {
	
	/**
     * To get the name of this EBenchmark calculation.
     * @return The name of this EBenchmark calculation.
     */
    public String getName();
    
    /**
     * To add a new {@code Facility} to this {@code EBenchmarkScaling}.
     * @return All parameters of the added Facility.
     */
	public ParameterListScaling addFacility();
	
	/**
	 * To add a new {@code Factory} to this {@code EBenchmarkScaling}.
	 * @return All parameters of the added factory.
	 */
	public ParameterListScaling addFactory();
	
	/**
	 * To add a new {@code Location} to this {@code EBenchmarkScaling}.
	 * @return The new location.
	 */
	public ILocation addLocation();
	
	/**
	 * To add a new {@code Company} to this {@code EBenchmarkScaling}.
	 * @return The new company.
	 */
	public ICompany addCompany();
	
	/**
	 * To add a new {@code IndustrialSector} to this {@code EBenchmarkScaling}.
	 * @return The new industrial sector.
	 */
	public IIndustrialSector addIndustrialSector();
	
	/**
	 * To add a new {@code Product} to this {@code EBenchmarkScaling}.
	 * @return The new product.
	 */
	public IProduct addProduct();
	
	/**
	 * To remove the last {@code Facility}.
	 */
	public void removeFacility();
	
	/**
	 * To remove the last {@code Factory}.
	 */
	public void removeFactory();
	
	/**
	 * To remove the last {@code Location}.
	 */
	public void removeLocation();
	
	/**
	 * To remove the last {@code Company}.
	 */
	public void removeCompany();
	
	/**
	 * To remove the last {@code IndustrialSector}.
	 */
	public void removeIndustrialSector();
	
	/**
	 * To remove the last {@code Product}.
	 */
	public void removeProduct();
	
	/**
	 * To set a new name for an existing {@code Facility}.
	 * @param facility the facility whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setFacilityName(IFacility facility, String newName)
			throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To set a new name for an existing {@code Factory}.
	 * @param factory the factory whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setFactoryName(IFactory factory, String newName)
			throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To set a new name for an existing {@code Location}.
	 * @param location the location whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setLocationName(ILocation location, String newName)
			throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To set a new name for an existing {@code Company}.
	 * @param company the company whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setCompanyName(ICompany company, String newName)
			throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To set a new name for an existing {@code IndustrialSector}.
	 * @param industry the industrial sector whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setIndustrialSectorName(
			IIndustrialSector industry, String newName)
					throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To set a new name for an existing {@code Product}.
	 * @param product the product whose name gets changed.
	 * @param newName the new name that is to be set.
	 * @throws IllegalArgumentException
	 * @throws Exception
	 */
	public void setProductName(IProduct product, String newName)
			throws IllegalArgumentException, DuplicateNameException;
	
	/**
	 * To get a {@code Facility} by its index (= time of creation). For example 
	 * getFacility(1) would return the first facility ever created.
	 * @param index the index of the facility in the creation list.
	 * @return The facility at the index position.
	 */
	public IFacility getFacility(int index);
	
	/**
	 * To get a {@code Factory} by its index (= time of creation). For example 
	 * getFactory(1) would return the first factory ever created.
	 * @param index the index of the factory in the creation list.
	 * @return The factory at the index position.
	 */
	public IFactory getFactory(int index);
	
	/**
	 * To get a {@code Location} by its index (= time of creation). For example 
	 * getLocation(1) would return the first location ever created.
	 * @param index the index of the location in the creation list.
	 * @return The location at the index position.
	 */
	public ILocation getLocation(int index);
	
	/**
	 * To get a {@code Company} by its index (= time of creation). For example 
	 * getCompany(1) would return the first company ever created.
	 * @param index the index of the company in the creation list.
	 * @return The company at the index position.
	 */
	public ICompany getCompany(int index);
	
	/**
	 * To get an {@code IndustrialSector} by its index (= time of creation). For 
	 * example getIndustrialSector(1) would return the first industrial sector 
	 * ever created.
	 * @param index the index of the industrial sector in the creation list.
	 * @return The industrial sector at the index position.
	 */
	public IIndustrialSector getIndustrialSector(int index);
	
	/**
	 * To get a {@code Product} by its index (= time of creation). For example 
	 * getProduct(1) would return the first product ever created.
	 * @param index the index of the product in the creation list.
	 * @return The product at the index position.
	 */
	public IProduct getProduct(int index);
	
	/**
	 * To get a {@code Facility} by it's ID or by it's name.
	 * @param facilityInformation the ID or the name of the facility.
	 * @return The facility that belongs to the facilityInformation.
	 * @throws NoSuchElementException
	 */
	public IFacility getFacility(String facilityInformation)
            throws NoSuchElementException;
	
	/**
	 * To get a {@code Factory} by it's ID or by it's name.
	 * @param factoryInformation the ID or the name of the factory.
	 * @return The factory that belongs to the factoryInformation.
	 * @throws NoSuchElementException
	 */
	public IFactory getFactory(String factoryInformation)
            throws NoSuchElementException;
	
	/**
	 * To get a {@code Location} by it's ID or by it's name.
	 * @param locationInformation the ID or the name of the location.
	 * @return The location that belongs to the locationInformation.
	 * @throws NoSuchElementException
	 */
	public ILocation getLocation(String locationInformation)
			throws NoSuchElementException;
	
	/**
	 * To get a {@code Company} by it's ID or by it's name.
	 * @param companyInformation the ID or the name of the company.
	 * @return The company that belongs to the companyInformation.
	 * @throws NoSuchElementException
	 */
	public ICompany getCompany(String companyInformation)
			throws NoSuchElementException;
	
	/**
	 * To get an {@code IndustrialSector} by it's ID or by it's name.
	 * @param industrialSectorInformation the ID or the name of the 
	 * industrial sector.
	 * @return The industrial sector that belongs to the 
	 * industrialSectorInformation.
	 * @throws NoSuchElementException
	 */
	public IIndustrialSector getIndustrialSector(
			String industrialSectorInformation) throws NoSuchElementException;
	
	/**
	 * To get a {@code Product} by it's ID or by it's name.
	 * @param productInformation the ID or the name of the product.
	 * @return The product that belongs to the productInformation.
	 * @throws NoSuchElementException
	 */
	public IProduct getProduct(String productInformation)
			throws NoSuchElementException;
	
	/**
	 * To get a list of all facilities that exist at the moment.
	 * @return All facilities.
	 */
	public List<IFacility> getFacilities();
	
	/**
	 * To get a list of all factories that exist at the moment.
	 * @return All factories.
	 */
	public List<IFactory> getFactories();
	
	/**
	 * To get a list of all locations that exist at the moment.
	 * @return All locations.
	 */
	public List<ILocation> getLocations();
	
	/**
	 * To get a list of all companies that exist at the moment.
	 * @return All companies.
	 */
	public List<ICompany> getCompanies();
	
	/**
	 * To get a list of all industrial sectors that exist at the moment.
	 * @return All industrial sectors.
	 */
	public List<IIndustrialSector> getIndustrialSectors();
	
	/**
	 * To get a list of all products that exist at the moment.
	 * @return All products.
	 */
	public List<IProduct> getProducts();

	/**
	 * To get the names of every facility that exists at the moment.
	 * @return The names of all facilities.
	 */
	public String[] getFacilityNames();
	
	/**
	 * To get the names of every factory that exists at the moment.
	 * @return The names of all factories.
	 */
	public String[] getFactoryNames();
	
	/**
	 * To get the names of every location that exists at the moment.
	 * @return The names of all locations.
	 */
	public String[] getLocationNames();
	
	/**
	 * To get the names of every company that exists at the moment.
	 * @return The names of all companies.
	 */
	public String[] getCompanyNames();
	
	/**
	 * To get the names of every industrial sector that exists at the moment.
	 * @return The names of all industrial sectors.
	 */
	public String[] getIndustrialSectorNames();
	
	/**
	 * To get the names of every product that exists at the moment.
	 * @return The names of all products.
	 */
	public String[] getProductNames();
		
	/**
	 * To build up an ArrayList called listManuMethodFacilitySets that contains 
	 * a list of Strings[] of size 2 called manuMethodFacilitySet. 
	 * <br>manuMethodFacilitySet[0] represents the manuMethodID. 
	 * <br>manuMethodFacilitySet[1] represents the facilityName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param facilityName the name of the facility to which the manufacturing 
	 * method of the manuMethodID gets added.
	 */
	public void generateListManuMethodFacilitySets(
			String manuMethodID,
			String facilityName);

	/**
	 * To build up an ArrayList called listFacilityFactorySets that contains 
	 * a list of Strings[] of size 3 called facilityFactorySet. 
	 * <br>facilityFactorySet[0] represents the manuMethodID.
	 * <br>facilityFactorySet[1] represents the facilityName.
	 * <br>facilityFactorySet[2] represents the factoryName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param facilityName the name of the facility.
	 * @param factoryName the name of the factory to which the facility of the 
	 * facilityName gets added.
	 */
	public void generateListFacilityFactorySets(
			String manuMethodID,
			String facilityName,
			String factoryName);
	
	/**
	 * To build up an ArrayList called listFactoryLocationSets that contains 
	 * a list of Strings[] of size 3 called factoryLocationSet. 
	 * <br>factoryLocationSet[0] represents the manuMethodID.
	 * <br>factoryLocationSet[1] represents the factoryName.
	 * <br>factoryLocationSet[2] represents the locationName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param factoryName the name of the factory.
	 * @param locationName the name of the location to which the factory of the 
	 * factoryName gets added.
	 */
	public void generateListFactoryLocationSets(
			String manuMethodID,
			String factoryName,
			String locationName);
	
	/**
	 * To build up an ArrayList called listLocationCompanySets that contains 
	 * a list of Strings[] of size 3 called locationCompanySet. 
	 * <br>locationCompanySet[0] represents the manuMethodID.
	 * <br>locationCompanySet[1] represents the locationName.
	 * <br>locationCompanySet[2] represents the companyName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param locationName the name of the location.
	 * @param companyName the name of the company to which the location of the 
	 * locationName gets added.
	 */
	public void generateListLocationCompanySets(
			String manuMethodID,
			String locationName,
			String companyName);
	
	/**
	 * To build up an ArrayList called listCompanyIndustrySets that contains 
	 * a list of Strings[] of size 3 called companyIndustrySet. 
	 * <br>companyIndustrySet[0] represents the manuMethodID.
	 * <br>companyIndustrySet[1] represents the companyName.
	 * <br>companyIndustrySet[2] represents the industryName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param companyName the name of the company.
	 * @param industryName the name of the industrial sector to which the 
	 * company of the companyName gets added.
	 */
	public void generateListCompanyIndustrySets(
			String manuMethodID,
			String companyName,
			String industryName);
	
	/**
	 * To build up an ArrayList called listFactoryProductSets that contains 
	 * a list of Strings[] of size 3 called factoryProductSet. 
	 * <br>factoryProductSet[0] represents the manuMethodID.
	 * <br>factoryProductSet[1] represents the factoryName.
	 * <br>factoryProductSet[2] represents the productName.
	 * @param manuMethodID the ID of the manufacturing method.
	 * @param factoryName the name of the factory.
	 * @param productName the name of the product to which the factory of the 
	 * factoryName gets added.
	 */
	public void generateListFactoryProductSets(
			String manuMethodID,
			String factoryName, 
			String productName);
	
	/**
	 * To add a all manufacturing methods to their selected facilities.
	 */
	public void addManuMethodsToFacilities();
	
	/**
	 * To add all facilities to their selected factories.
	 */
	public void addFacilitiesToFactories();
	
	/**
	 * To add all factories to their selected locations.
	 */
	public void addFactoriesToLocations();
	
	/**
	 * To add all locations to their selected companies.
	 */
	public void addLocationsToCompanies();
	
	/**
	 * To add all companies to their selected industrial sectors.
	 */
	public void addCompaniesToIndustries();
	
	/**
	 * To add all factories to their selected products.
	 */
	public void addFactoriesToProducts();
	
	/**
	 * To check whether:<br>
	 * - one facility is assigned to only one factory,<br>
	 * - one factory is assigned to only one location,<br>
	 * - one location is assigned to only one company,<br>
	 * - one company is assigned to only one industrial sector,<br>
	 * - one factory is assigned to only one product.<br>
	 * If one of these rules is violated show a warning message.
	 */
	public void testScalingAssignment();

}
